/*
 * @Author: 来自火星的码农 15122322+heyzhi@user.noreply.gitee.com
 * @Date: 2025-10-10 18:46:16
 * @LastEditors: 来自火星的码农 15122322+heyzhi@user.noreply.gitee.com
 * @LastEditTime: 2025-10-10 20:22:31
 * @FilePath: /GateServer/src/redis/redisconnectionpool.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include "redisconnectionpool.h"
#include <cstddef>
#include <hiredis/hiredis.h>
#include <hiredis/read.h>
#include <mutex>
#include "../util/logger.h"

namespace Yizhi{

    RedisConnectionPool::RedisConnectionPool(std::string host,int port,std::string psw,size_t size)
    :m_host(host)
    ,m_port(port)
    ,m_psw(psw)
    ,m_size(size){
        for(auto i=0;i<m_size;i++){
            auto con=CreateConnection();
            if(con) m_connections.push(con);
        }
    }

    RedisConnectionPool::~RedisConnectionPool(){
        close();
    }

    redisContext* RedisConnectionPool::CreateConnection(){
        redisContext* context=redisConnect(m_host.c_str(),m_port);
            if(context==nullptr||context->err!=0){
                if(context!=nullptr){
                    redisFree(context);
                    return nullptr;
                }
            }

            auto reply=(redisReply*)redisCommand(context,"AUTH %s", m_psw.c_str());
            if(reply==nullptr||reply->type==REDIS_REPLY_ERROR){
                if(reply!=nullptr){
                    freeReplyObject(reply);
                    LOG_ERROR("redis 认证失败"+m_psw);
                    return nullptr;
                }
            }
            LOG_DEBUG("redis connect success");

            return context;
    }

    void RedisConnectionPool::close(){
        m_stop=true;
        m_cond.notify_all();
        std::lock_guard<std::mutex> lock(m_mutex);
        while(!m_connections.empty()){
            m_connections.pop();
        }
        
    }

    void RedisConnectionPool::ReturnConnection(redisContext* con){
        if(!con){
            return;
        }   
        std::lock_guard<std::mutex> lock(m_mutex);
       
        if(m_stop){
            return;
        }

        m_connections.push(con);

        m_cond.notify_one();
        
    }
    redisContext* RedisConnectionPool::GetConnection(){
        std::unique_lock<std::mutex> lock(m_mutex);
        m_cond.wait(lock,[this]{
            return m_stop||!m_connections.empty();
        });
        auto con=std::move(m_connections.front());
        if(m_stop||!con){
            return nullptr;
        }
        m_connections.pop();
        return con;
    }

}